namespace Microsoft.ServiceModel.Samples.Discovery.Protocol
{
    using System;
    using System.Text;
    using System.Xml;

    public sealed class DebugUtility
    {
        DebugUtility()
        {
        }

        public static string ToString(MatchCriteria criteria)
        {
            return ToString(string.Empty, criteria);
        }

        public static string ToString(string tab, MatchCriteria criteria)
        {
            if (tab == null)
                throw new ArgumentNullException("tab");
            if (criteria == null)
                throw new ArgumentNullException("criteria");

            StringBuilder builder = new StringBuilder();
            builder.AppendLine(tab + "*** " + criteria.GetType().Name + " ***");

            if (criteria != null)
            {
                builder.Append(ToString(AddTab(tab), criteria.Scopes));
                builder.Append(ToString(AddTab(tab), criteria.Types));
                builder.Append(ToString(AddTab(tab), criteria.AnyElements));
                builder.Append(ToString(AddTab(tab), criteria.AnyAttributes));
            }

            return builder.ToString();
        }
        
        public static string ToString(ServiceProperties serviceProperties)
        {   
            return ToString(string.Empty, serviceProperties);
        }

        public static string ToString(string tab, ServiceProperties serviceProperties)
        {
            if (serviceProperties == null)
                throw new ArgumentNullException("serviceProperties");
            
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(tab + "*** " + serviceProperties.GetType().Name + " ***");

            if (serviceProperties != null)
            {
                builder.Append(AddTab(tab));
                builder.AppendLine("EndpointAddress = " + serviceProperties.EndpointAddress);

                builder.Append(ToString(AddTab(tab), serviceProperties.Scopes));
                builder.Append(ToString(AddTab(tab), serviceProperties.Types));

                Bye bye = serviceProperties as Bye;
                if (bye != null)
                {
                    if (bye.MetadataVersionSpecified)
                    {
                        builder.Append(AddTab(tab));
                        builder.AppendLine("MetadataVersion = " + bye.MetadataVersion);
                    }
                }
                else
                {
                    builder.Append(AddTab(tab));
                    builder.AppendLine("MetadataVersion = " + serviceProperties.MetadataVersion);
                }

                builder.Append(ToString(AddTab(tab), serviceProperties.AnyElements));
                builder.Append(ToString(AddTab(tab), serviceProperties.AnyAttributes));
            }

            return builder.ToString();
        }

        static string AddTab(string tab)
        {
            return AddTab(tab, 1);
        }

        static string AddTab(string tab, int level)
        {
            if (tab == null)
                throw new ArgumentNullException("tab");

            for (int i = 0; i < level; i++)
                tab += "\t";

            return tab;
        }

        public static string ToString(ScopeCollection scopes)
        {
            return ToString(string.Empty, scopes);
        }

        public static string ToString(string tab, ScopeCollection scopes)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(tab + "Scopes = ");

            if (scopes != null)
            {
                foreach (Uri uri in scopes)
                {
                    builder.AppendLine(AddTab(tab) + uri.ToString());
                }
            }

            return builder.ToString();
        }

        public static string ToString(ContactTypeCollection types)
        {
            return ToString(string.Empty, types);
        }

        public static string ToString(string tab, ContactTypeCollection types)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(tab + "Types = ");

            if (types != null)
            {
                foreach (XmlQualifiedName qname in types)
                {
                    builder.AppendLine(AddTab(tab) + qname.ToString());
                }
            }

            return builder.ToString();
        }

        public static string ToString(XmlElement[] anyElements)
        {
            return ToString(string.Empty, anyElements);
        }

        public static string ToString(string tab, XmlElement[] anyElements)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(tab + "AnyElements = ");

            if (anyElements != null)
            {
                foreach (XmlElement element in anyElements)
                {
                    builder.AppendLine(AddTab(tab) + element.OuterXml);
                }
            }

            return builder.ToString();
        }

        public static string ToString(XmlAttribute[] anyAttributes)
        {
            return ToString(string.Empty, anyAttributes);
        }

        public static string ToString(string tab, XmlAttribute[] anyAttributes)
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(tab + "AnyAttributes = ");

            if (anyAttributes != null)
            {
                foreach (XmlAttribute attr in anyAttributes)
                {
                    builder.AppendLine(AddTab(tab) + attr.OuterXml);
                }
            }

            return builder.ToString();
        }
    }
}
